<template>
	<div>
		<el-dialog
			title="数据响应结果"
			v-model="state.dashboardDataFilterVisible"
			:fullscreen="false"
			class="dashboard-data-filter"
			width="50vw"
			top="10vh">
			<div style="margin-bottom: 5px; color: white">
				<div class="callback-container">
					<div class="callback-container-label">回调字段：</div>
					<div class="callback-container-variable">
						<el-tag
							v-for="tag in state.tmpInteractionFilterArgs"
							:key="tag"
							closable
							:disable-transitions="true"
							@close="handleCloseFilterArg(tag)">
							{{ tag }}
						</el-tag>
						<el-input
							class="input-new-tag"
							v-if="state.inputVisible"
							v-model="state.inputValue"
							ref="saveTagInput"
							size="small"
							@change="handleFilterArgConfirm"></el-input>
						<el-button
							type="primary"
							v-else
							class="button-new-tag"
							size="small"
							@click="showFilterArgInput">
							添加回调
						</el-button>
					</div>
				</div>
				<div>function filter(data, callbackArgs) {</div>
				<v-ace-editor
					class="data-filter-code-editor"
					v-model:value="state.filterFunctionBody"
					theme="monokai"
					:options="Options"
					ref="callbackEditor"></v-ace-editor>
				<div>}</div>
			</div>
			<div class="response-data-container">
				<span style="color: white">数据响应结果</span>
				<v-ace-editor
					class="data-filter-code-editor"
					v-model:value="state.filterFunctionResult"
					lang="json"
					theme="monokai"
					:options="Options"
					ref="responseEditor"></v-ace-editor>
			</div>
			<template #footer>
				<div class="dialog-footer">
					<el-row class="data-filter-footer-btn">
						<el-col :span="4">
							<el-button type="primary" @click="handleTestDataFilter" style="float: left">
								测试
							</el-button>
						</el-col>
						<el-col :span="10" style="height: 1px"></el-col>
						<el-col :span="10">
							<el-button @click="handleCloseFilter">取消</el-button>
							<el-button type="primary" @click="handleSaveFilter">保存</el-button>
						</el-col>
					</el-row>
				</div>
			</template>
		</el-dialog>
	</div>
</template>

<script lang="ts" setup>
import { onMounted, ref, reactive, watch, toRefs, nextTick } from 'vue';
import './aceConfigs';
import { VAceEditor } from 'vue3-ace-editor';
import _ from 'lodash';
import { usePrimaryStore } from '@/store';

const store = usePrimaryStore();

const props = defineProps({
	visible: {
		type: Boolean,
		default: false
	},
	instance: {
		type: Object,
		default() {
			return {};
		}
	},
	dataToResponseData: {
		type: String,
		default: ''
	}
});
const state = reactive({
	dashboardDataFilterVisible: props.visible,
	filterFunctionBody: 'return data', //回调栏 CodeEditor 中的值

	inputVisible: false,
	inputValue: '',
	tmpInteractionFilterArgs: _.cloneDeep(props.instance.filterCbVar),
	filterFunctionResult: props.dataToResponseData,

	oldFilterCallbackArgs: []
});
const Options = reactive({
	// codemirror options
	useWorker: true, // 启用语法检查,必须为true
	enableBasicAutocompletion: true, // 自动补全
	enableLiveAutocompletion: true, // 智能补全
	enableSnippets: true, // 启用代码段
	showPrintMargin: false, // 去掉灰色的线，printMarginColumn
	highlightActiveLine: true, // 高亮行
	highlightSelectedWord: true, // 高亮选中的字符
	tabSize: 4, // tab锁进字符
	fontSize: 14, // 设置字号
	wrap: false // 是否换行
});
const emit = defineEmits(['update:visible', 'change', 'getDataFilter']);

// const codemirror = computed(() => {
// 	return myCm.value.codemirror;
// });
watch(
	() => props.visible,
	(nv) => {
		state.dashboardDataFilterVisible = nv;
	}
);
watch(
	() => state.dashboardDataFilterVisible,
	(nv) => {
		emit('update:visible', nv);
	}
);

function handleCloseFilterArg(target: any) {
	state.tmpInteractionFilterArgs.splice(state.tmpInteractionFilterArgs.indexOf(target), 1);
	// 移除监听
	store.removeCallBackListener({ listener: props.instance.uuid, target: target });
}

function handleFilterArgConfirm() {
	const inputValue = state.inputValue;
	if (inputValue) {
		state.tmpInteractionFilterArgs.push(inputValue);
		// 添加监听
		store.addCallBackListener({ listener: props.instance.uuid, target: inputValue });
	}
	state.inputVisible = false;
	state.inputValue = '';
}
const saveTagInput = ref();
function showFilterArgInput() {
	state.inputVisible = true;
	nextTick(() => {
		saveTagInput.value.focus();
	});
}

function handleTestDataFilter() {
	// 尝试从回调池里取字段值，用来处理filter
	const callbackValues = store.getCallbackValuesByTargets({
		targets: state.tmpInteractionFilterArgs,
		visitor: props.instance.uuid,
		data0: true
	});

	const filter = new Function('data', 'callbackArgs', state.filterFunctionBody);
	// 调用生成好的函数并传入实际参数
	const result = JSON.stringify(
		filter(JSON.parse(props.dataToResponseData), callbackValues),
		null,
		4
	);
	state.filterFunctionResult = result;
}

function handleCloseFilter() {
	// 移除监听
	state.oldFilterCallbackArgs.forEach((target: any) => {
		store.removeCallBackListener({ listener: this.instance.uuid, target: target });
	});
	state.dashboardDataFilterVisible = false;
}

function handleSaveFilter() {
	// 将回调相关字段存入instance
	// this.instance.filterCbVar = this.tmpInteractionFilterArgs
	state.oldFilterCallbackArgs = state.tmpInteractionFilterArgs;
	// TODO: 如果过滤器未进行保存，需要移除监听

	const dataFilter = {
		filterCbVar: state.tmpInteractionFilterArgs,
		filterFn: state.filterFunctionBody
	};

	// 将过滤器临时信息向上传递
	emit('getDataFilter', _.clone(dataFilter));

	// this.setConfiguredDataToInstance(this.instance.uuid, {
	//   dataFormatter: this.instance.dataFormatter,
	// })
}

onMounted(() => {});
defineExpose({ ...toRefs(state) });
</script>

<style lang="scss" scoped>
:deep(.dashboard-data-filter) {
	padding: 16px;
	color: white;
	transition:
		transform 0.3s cubic-bezier(0.7, 0.3, 0.1, 1),
		height 0s ease 0.3s,
		width 0s ease 0.3s;
	z-index: -1;
}

::v-deep .el-divider--horizontal {
	margin: 12px 0;
}

/* 抽屉打开时的样式 */
.data-filter-code-editor {
	width: 100%;
	height: 245px;
	overflow: hidden;
	transition:
		transform 0.3s cubic-bezier(0.7, 0.3, 0.1, 1),
		height 0s ease 0.3s,
		width 0s ease 0.3s;
	border: solid 1px var(--primary);
	border-radius: 2px;
}

.data-filter-footer-btn {
}

.callback-container {
	margin: 8px 0;
	display: flex;

	&-label {
		display: flex;
		align-items: center;
		flex-basis: 5rem;
	}

	&-variable {
		flex: 1;

		> span {
			/* margin-top: 8px; */
			margin-bottom: 8px;
		}

		span:first-child {
			margin-left: 10px;
		}
	}
}

.switch {
	margin-bottom: 10px;
}

.el-tag + .el-tag {
	margin-left: 10px;
}
.button-new-tag {
	margin-left: 10px;
	height: 32px;
	line-height: 30px;
	padding-top: 0;
	padding-bottom: 0;
}
.input-new-tag {
	width: 90px;
	margin-left: 10px;
	vertical-align: bottom;
}
</style>
